/**
 * @author Aleksandr Smirnov (luc@hot.ee)
 */

var MousePanning = SMap.MousePanning = SMap.Class({
	init: function(view) {
		ensureImplements(view, ViewportInterface);
		
		var proj = view.getProjectionModel();
		var div = view.getSurfaceElement();
		
		var startDragPoint, startDragMapCenter;
		
		function onDragStart(mouse) {
			startDragPoint = mouse;
			startDragMapCenter = proj.getCenterXY();
		}
		
		function onDragMove(mouse) {
			var p = new XY(
				mouse.x - startDragPoint.x + startDragMapCenter.x,
				mouse.y - startDragPoint.y + startDragMapCenter.y
			);
			proj.setCenterXY(p);
		}
		
		function onDragEnd() {
			if(this.onDragComplete)
				this.onDragComplete();
		}
		
		var dragable = new Dragable(div, onDragStart, onDragMove, onDragEnd);
	}
});

var Dragable = function(elem, onStart, onMove, onEnd) {
	var dragging = false;
	var eventList = [];
	
	bindDOM(elem, "mousedown", onMouseDown);
	
	function onMouseDown(e) {
		if(onStart) {
			onStart({ x: Event.pointerX(e), y: Event.pointerY(e) });
		};
		
		if (elem.setCapture) {
			elem.setCapture();
		}
		
		eventList.push(bindDOM(document, "mouseup", onMouseUp));
		eventList.push(bindDOM(document, "mousemove", onMouseMove));
		eventList.push(bindDOM(window, "mouseout", onWindowMouseOut));
		
		dragging = true;
	}
	
	function onMouseUp(e) {
		dragging = false;
		
		for(var i=0; i<eventList.length; i++) {
			unbindDOM(eventList.pop());
		};
			
		if (elem.releaseCapture) {
			elem.releaseCapture();
		}
		
		if(onEnd) {
			onEnd();
		};
	}
	
	function onMouseMove(e) {
		if (!dragging) return;
		
		if(onMove) {
			onMove({ x: Event.pointerX(e), y: Event.pointerY(e)});
		}
	}
	
	function onWindowMouseOut(e) {
		// mozilla & opera
		var t = e.relatedTarget;
		if (!t) t = e.toElement;
		if (dragging && !t) {
			onMouseUp();
		}
	}
}
